﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class DownloadFileInfo
{
    public string FileName;//文件名字
    public string FilePath;//文件下载保存位置
    public string FileDirPath;//文件所在文件夹路径

    public DownloadFileInfo() { }

    public DownloadFileInfo(string fileName)
    {
        FileName = fileName;

        FilePath = IPDownloadExtension.DownloadFileSavePathPrefix + fileName;
        FilePath = FilePath.Replace('\\', '/');

        FileDirPath = FilePath.Substring(0, FilePath.LastIndexOf('/'));
    }
}

/// <summary>
/// https://blog.csdn.net/qq_37421018/article/details/102079348?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
/// </summary>
public class DownloadJobHandler : DownloadHandlerScript
{
    public FileStream fileStream;
    public DownloadFileInfo fileInfo;

    private string url;
    private string tempFilePath;
    private long fileTotalLength;
    private long fileDownloadedLength;//已经下载的长度
    public long FileDownloadedLength
    {
        get
        {
            return fileDownloadedLength;
        }
    }

    public event Action<long> OnReceiveTotalLengthEvent = null;//获取到文件整体大小
    public event Action<long> OnReceiveRemainingLengthEvent = null;//获取剩余需要下载的大小
    public event Action<float> OnReceiveDataEvent = null;
    public event Action<string> OnDownloadJobCompleteEvent = null;

    public DownloadJobHandler(string url, string appointName = "") : base(new byte[1024 * 200])
    {
        this.url = url;

        string fileName = !string.IsNullOrEmpty(appointName) ? appointName : IPDownloadExtension.GetNameByUrl(url);//无指定命名使用解析出的备用命名
        DownloadFileInfo info = new DownloadFileInfo(fileName);
        fileInfo = info;

        tempFilePath = info.FilePath + IPDownloadExtension.DownloadFileNameSuffix;//InterfacePlatformTemp
        fileStream = new FileStream(tempFilePath, FileMode.Append, FileAccess.Write);
        fileDownloadedLength = fileStream.Length;
    }

    /// <summary>
    /// 获取本次下载所需要的大小
    /// </summary>
    protected override void ReceiveContentLength(int contentLength)
    {
        //base.ReceiveContentLength(contentLength);

        if (contentLength == 0)
        {
            Debug.Log("下载完成");
            CompleteContent();
        }

        fileTotalLength = fileDownloadedLength + contentLength;
        if (OnReceiveTotalLengthEvent != null)
        {
            OnReceiveTotalLengthEvent.Invoke(fileTotalLength);
        }
        if (OnReceiveRemainingLengthEvent != null)
        {
            OnReceiveRemainingLengthEvent.Invoke(contentLength);
        }
    }

    protected override bool ReceiveData(byte[] data, int dataLength)
    {
        if (data == null || data.Length == 0)
        {
            Debug.LogFormat("下载文件{0}失败，没有获取到数据", fileInfo.FileName);

            return false;
        }

        if (fileStream != null)
        {
            fileStream.Write(data, 0, dataLength);
        }
        fileDownloadedLength += dataLength;
        float progress = (float)fileDownloadedLength / fileTotalLength;
        if (OnReceiveDataEvent != null)
        {
            OnReceiveDataEvent.Invoke(progress);
        }

        return true;
    }

    protected override void CompleteContent()
    {
        fileStream.Close();
        fileStream.Dispose();

        if (File.Exists(tempFilePath))
        {
            if (File.Exists(fileInfo.FilePath))
            {
                File.Delete(fileInfo.FilePath);
            }
            File.Move(tempFilePath, fileInfo.FilePath);//将临时文件改成下载完成的文件

            Debug.LogFormat("下载完成{0}", fileInfo.FileName);
        }
        else
        {
            Debug.LogFormat("下载失败{0}", fileInfo.FileName);
        }

        if (OnDownloadJobCompleteEvent != null)
        {
            OnDownloadJobCompleteEvent.Invoke(fileInfo.FilePath);
        }
    }

    public void DisposeJob(bool deleteTempFile = false)
    {
        fileStream.Close();
        fileStream.Dispose();

        if (deleteTempFile)
        {
            if (File.Exists(tempFilePath))
            {
                File.Delete(tempFilePath);
            }
        }

        Dispose();
    }
}
